﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace TestCppLib.NET
{
    public class NativeLoader
    {
        private static readonly object SyncRoot = new object();
        /// <summary>
        /// 
        /// </summary>
        internal static bool IsInit { get; private set; } = false;

#pragma warning disable CA2255
        //[ModuleInitializer]
        internal static void Init()
        {
//             if (IsInit) return;
//             lock (SyncRoot)
//             {
//                 if (IsInit) return;
//                 NativeLibrary.SetDllImportResolver(typeof(NativeLoader).Assembly, ImportResolver);
//                 IsInit = true;
//             }
        }
#pragma warning restore CA2255

        static NativeLoader()
        {
            Init();
        }

        private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
        {
//             var path = GetPath(libraryName, assembly);
//             if (!File.Exists(path)) throw new FileNotFoundException($"cannot found library with name {libraryName}");
//             IntPtr h = NativeLibrary.Load(path);
//             return h;
return IntPtr.Zero;
        }

        private static string GetPath(string libraryName, Assembly assembly)
        {
            if(string.IsNullOrEmpty(libraryName)) throw new ArgumentNullException(nameof(libraryName));
            if (assembly == null) throw new ArgumentNullException(nameof(assembly));
#pragma warning disable IL3000
            string location = assembly.Location;
#pragma warning restore IL3000
            string rootPath = Path.GetDirectoryName(location) ?? throw new DllNotFoundException($"cannot load dll with path {location}");
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return Path.Combine(rootPath, "runtimes", "win-x64", "native", $"{libraryName}.dll");
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                return Path.Combine(rootPath, "runtimes", "linux-x64", "native", $"lib{libraryName}.so");
            }
            else throw new NotSupportedException("Not supported form current system");
        }
    }
}
